package com.example.demo.interceptor;

import com.example.demo.pojo.User.User;
import com.example.demo.service.UserService;
import com.example.demo.utils.TokenUtil.JwtUtils;
import com.example.demo.utils.TokenUtil.OnlineUserStatsService;
import com.example.demo.utils.TokenUtil.spiltUtils;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.annotation.Resource;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import static com.example.demo.utils.ConstantUtils.*;

@Component
@Slf4j
public class UserInterceptor implements HandlerInterceptor {

    @Resource
    private UserService userService;

    @Resource
    private OnlineUserStatsService onlineUserStatsService;

    @Override
    public boolean preHandle(HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull Object handler) {
        // 获取用户登录凭证
        Cookie[] cookies = request.getCookies();
        if (cookies != null) {
            for (Cookie cookie : cookies) {
                if (COOKIE_NAME.equals(cookie.getName())) {
                    String token = cookie.getValue();
                    // Token无效，已在validateToken方法中设置了响应状态
                    return validateToken(token, request, response);
                }
            }
        }
        // 如果请求中没有token，返回401状态码
        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        log.info("缺少认证Token => " + request.getRequestURI());
        return false;
    }

    private boolean validateToken(String token, HttpServletRequest request, HttpServletResponse response) {
        String uri = request.getRequestURI();
        log.info("访问uri => " + uri);

        try {
            Claims claims = JwtUtils.parseJWT(token);
            String pe = JwtUtils.getUserName(claims); // 获取用户登录名
            if (pe != null) {
                String userName = spiltUtils.getUserName(pe);
                // 已登录
                User user = userService.getByUserName(userName);
                String role = user.getRole();
                if (user.getStatus() == STATUS_DISABLED) {
                    log.info(user.getUserName() + " 用户已被禁用！");
                    response.setStatus(HttpServletResponse.SC_FORBIDDEN);
                    return false;
                }
                // 检查用户是否在Redis的在线用户集合中
                Double userScore = onlineUserStatsService.getScore(user.getId());
                if (userScore == null) {
                    // 用户不在在线用户集合中，可能由于长时间不活跃被清除
                    log.info(user.getUserName() + " 用户可能由于长时间不活跃被清除");
                    response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
                    return false;
                }
                // 如果角色是vip，则放行所有请求
                if (USER_ROLE.equals(role) || VIP_USER_ROLE.equals(role)) {
                    // 在这里可以根据需要进行权限验证等操作
                    // 更新在线用户状态
                    onlineUserStatsService.online(user.getId());
                    log.info("鉴权通过 => " + uri);
                    return true;
                }
            }
        } catch (ExpiredJwtException e) {
            log.info("JWT过期 => " + uri);
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            return false;
        } catch (Exception e) {
            log.error("JWT验证失败 => " + uri, e);
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            return false;
        }
        log.info("鉴权失败 => " + uri);
        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        return false;
    }
}

